package com.huluobo.jetpackkotlindemo.paging

import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.paging.LoadState
import androidx.recyclerview.widget.LinearLayoutManager
import com.huluobo.jetpackkotlindemo.databinding.ActivityPaging2Binding
import com.huluobo.jetpackkotlindemo.viewbinding.BaseActivity
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch

/**
 * Paging:是page的进行时,也就是分页框架,之前在flutter中学习过EasyRefresh,SmartRefresh,都是刷新框架,用于触发页码的刷新
 * 有个footer或者header来用于刷新或者加载,通过footer加载数据,page++这种情况
 * Paging3是Google最新推出的分页加载库
 * 1.Paging最关键的数据传递 通过getPagingData().cachedIn(viewModelScope)生成一个数据流,在activity当中,
 * 我们可以通过viewModel.getPagingData().collect接收器来进行数据的接收
 * 2.通过PagingConfig来设置预加载的大小,前后翻页的key
 * 3.通过RepoPagingSource来重写load方法
 * 4.RepoPagingSource才是真正的数据源产生的位置,在这当中,连接了网络请求
 * 5.PagingDataAdapter是配合Paging使用的,构造中需要个DiffUtil来管理item中数据是否一致
 * 6.LoadStateAdapter 是一个脚布局,主要的作用是有一个状态LoadState,通过这状态可以对应的去写回调
 * 7.Paging给Adapter传递数据的位置是mAdapter.submitData(it) 通过协程的Flow从ViewModel中拿到数据并填充
 *
 * 8.RemoteMediator 远程调度器 现在的请求都是一个单一数据源,当有网的时候,从网络获取数据,当新增需求,无网状态下也需要去获取数据
 * 一个数据源是有网状态,另一个数据源是无网状态
 */
class PagingActivity : BaseActivity<ActivityPaging2Binding>() {
    override fun getViewBinding(): ActivityPaging2Binding =
        ActivityPaging2Binding.inflate(layoutInflater)

    //从view中需要拿到数据源
    private val viewModel by lazy {
        ViewModelProvider(this).get(PagingViewModel::class.java)
    }

    //Recyclerview的适配器
    private val mAdapter: RepoAdapter = RepoAdapter()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //设置刷新框架的监听器
        mViewBinding.refreshLayout.setOnRefreshListener {
            //当刷新框架刷新时,适配器也跟着刷新
            mAdapter.refresh()
        }

        mViewBinding.recycleView.layoutManager = LinearLayoutManager(this)
        //给适配器添加footer
        mViewBinding.recycleView.adapter = mAdapter.withLoadStateFooter(FooterAdapter {
            //footer中的构造方法中需要传递一个适配器的重试方法
            //这是kotlin的高阶函数
            mAdapter.retry()
        })

//        lifecycleScope.launch {
//            viewModel.getPagingData().collect {
//                //通过协程,接收viewModel的数据流,把数据流填充到adapter当中
//                mAdapter.submitData(it)
//            }
//        }
        viewModel.getPagingData2(this).observe(this, {
            mAdapter.submitData(lifecycle, it)
        })

        //监听加载状态
        mAdapter.addLoadStateListener {
            when (it.refresh) {
                is LoadState.NotLoading -> {
                    mViewBinding.recycleView.visibility = View.VISIBLE
                    mViewBinding.refreshLayout.isRefreshing = false
                }

                is LoadState.Loading -> {
                    mViewBinding.refreshLayout.isRefreshing = true
                    mViewBinding.recycleView.visibility = View.VISIBLE
                }

                is LoadState.Error -> {
                    val state = it.refresh as LoadState.Error
                    mViewBinding.refreshLayout.isRefreshing = false
                    Toast.makeText(this, "读取失败:${state.error.message}", Toast.LENGTH_SHORT).show()
                }
            }
        }

    }
}